package com.zd.filter;



import com.alibaba.fastjson2.JSON;
import com.zd.domain.Result;
import com.zd.domain.TokenState;
import com.zd.domain.User;
import com.zd.mapper.UserMapper;
import com.zd.service.user.UserService;
import com.zd.service.user.impl.UserServiceImpl;
import com.zd.utils.JWTUtils;
import jakarta.servlet.annotation.WebFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@WebFilter("/*")
public class JwtAuthenticationFilter implements Filter {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;

        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String token = request.getParameter("token");

        String longToken = request.getParameter("longToken");

        //获取到用户请求的Servlet路径
        String servletPath = request.getServletPath();

        if ("/login".equals(servletPath) || "/phoneLogin".equals(servletPath)){
            filterChain.doFilter(request,response);

            return; //需要加上return，否则程序放行后会继续执行下面的代码
        }

        //解析token
        TokenState tokenState = JWTUtils.parseJWT(token);

        System.out.println(tokenState.getUserID());

        Result<User> result = new Result();

        //token续期问题,条件-1，-2等在JWTUtils类中定义
        switch (tokenState.getNum()){
            case -1:
                //表明短时间token已过期，需要再验证长时间token是否过期，如果都过期，则重新登录
                tokenState = JWTUtils.parseJWT(longToken);

                if (tokenState.getNum() != -1){
                    //给短时间续期
                    token = JWTUtils.createJWT(1000*60*30,tokenState.getUserID());

                    //给长时间重新生成token
                    longToken = JWTUtils.createJWT(1000*60*60*24*7,tokenState.getUserID());

                    //数据查取到用户对象，此处应该从数据库中查询userid对应的user对象
                    //根据token中保存的userID查询数据库中的对象信息
//                    UserService userService = new UserServiceImpl();
//                    User user = userService.findByUserID(tokenState.getUserID());

                    User user = userMapper.findByUserID(tokenState.getUserID());
                    //如果查询不到对象，则让客户端重新登录
//                    if (user == null){
//                        //重定向到登录页面（暂时用baidu代替）
//                        result.setCode(7000);
//                        result.setMsg("用户id有误，无法找到用户");
//                        response.sendRedirect("http://www.baidu.com");
//                    }else {  //如果查询到对象，则继续操作

                        //将短时间token和长时间token存入user中，再通过result.setData(user)，将token和longToken传给客户端
                        user.setToken(token);
                        user.setLongToken(longToken);

                        result.setCode(2000);
                        result.setMsg("续期成功！");
                        result.setData(user);
//                    }

                }else {
                    result.setCode(4000);
                    result.setMsg("续期失败，登录状态已过期！");
                }
                break;

            case -2:
                //篡改情况处理：串改了签名导致无法进行验证，需要用户重新登录
                result.setCode(9000);
                result.setMsg("非法操作登陆系统！");

                //用户非法操作，此时强制让用户重新登录(暂时用百度代替登录页面)
                response.sendRedirect("http://www/baidu.com");
                break;

            default:
                //如果token时间都没有过期，并且条件都符合，就让该过滤器放行，用户可继续操作系统
                filterChain.doFilter(request,response);
                return;   //需要加上return，否则程序放行后会继续执行下面的代码
        }


        response.setContentType("application/json;charset=utf-8");

        //写出json
        String json = JSON.toJSONString(result);

        response.getWriter().print(json);

    }


    @Override
    public void destroy() {

    }
}
